package com.unibuy.smartdevice;

import android.os.Build;
import android.app.Application;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import com.unibuy.smartdevice.controller.DevController;
import com.unibuy.smartdevice.controller.DevXinYuanController;
import com.unibuy.smartdevice.database.MemoDao;
import com.unibuy.smartdevice.database.ProductsDao;
import com.unibuy.smartdevice.database.SettingsDao;
import com.unibuy.smartdevice.database.SlotsDao;
import com.unibuy.smartdevice.devices.ComPort;
import com.unibuy.smartdevice.devices.DevXinYuan;
import com.unibuy.smartdevice.devices.Rs232Dev;
import com.unibuy.smartdevice.devices.SlotField;
import com.unibuy.smartdevice.devices.UsbDev;
import com.unibuy.smartdevice.exception.ErrorCode;
import com.unibuy.smartdevice.exception.Logs;
import com.unibuy.smartdevice.exception.LogsEmptyException;
import com.unibuy.smartdevice.exception.LogsNoSuchElementException;
import com.unibuy.smartdevice.exception.LogsUnsupportedOperationException;
import com.unibuy.smartdevice.structure.AccessCodeStructure;
import com.unibuy.smartdevice.structure.CashSetStructure;
import com.unibuy.smartdevice.structure.DeliveryStructure;
import com.unibuy.smartdevice.structure.FreeGiftStructure;
import com.unibuy.smartdevice.structure.MemberVerificationStructure;
import com.unibuy.smartdevice.structure.MemoStructure;
import com.unibuy.smartdevice.structure.ReportAccessCodeStructure;
import com.unibuy.smartdevice.structure.BuyStructure;
import com.unibuy.smartdevice.structure.DevSetStructure;
import com.unibuy.smartdevice.structure.EsunpayStructure;
import com.unibuy.smartdevice.structure.GreenInvoiceStructure;
import com.unibuy.smartdevice.structure.GreenpayMerchantStructure;
import com.unibuy.smartdevice.structure.GreenpaySettingStructure;
import com.unibuy.smartdevice.structure.InvoiceItemStructure;
import com.unibuy.smartdevice.structure.InvoiceStructure;
import com.unibuy.smartdevice.structure.MachineStructure;
import com.unibuy.smartdevice.structure.MarketingPlanStructure;
import com.unibuy.smartdevice.structure.PostInvoiceByGreenStructure;
import com.unibuy.smartdevice.structure.ProductStructure;
import com.unibuy.smartdevice.structure.ReportDispatchInfoStructure;
import com.unibuy.smartdevice.structure.ReportFlowInfoStructure;
import com.unibuy.smartdevice.structure.ReportFreeGiftCodeStructure;
import com.unibuy.smartdevice.structure.ReportInvoiceInfoStructure;
import com.unibuy.smartdevice.structure.ReportSlotListStructure;
import com.unibuy.smartdevice.structure.SettingStructure;
import com.unibuy.smartdevice.structure.SlotStructure;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.tools.ToastHandlerMain;
import com.unibuy.smartdevice.tools.Tools;
import com.unibuy.smartdevice.ui.FontendActivity;
import com.unibuy.smartdevice.ui.tools.VideoEoxPlayer;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class MyApp extends Application {
    private Logs logs;
    private static MyApp instance;
    public static MyApp getInstance() {
        return instance;
    }
    private int screenWidthPx;
    private int screenHeightPx;
    private int closeSlot;
    private float density;
    private ComPort comPort1ByXinYuan;
    private ComPort comPort2ByNFCPay;
    private ComPort comPort3ByFlower;
    private List<ProductStructure> uploadProductList;
    private List<DeliveryStructure> uploadDeliveryList;
    private List<ProductStructure> productList;
    private List<DeliveryStructure> deliveryList;
    private List<String> fontendAdUrlString;
    private Map<Integer, List<SlotStructure>> slotMap;
    private List<MarketingPlanStructure> marketingPlanList;
    private List<BuyStructure> buyList;
    private CashSetStructure cashSetStructure;
    private AccessCodeStructure accessCodeStructure;
    private FreeGiftStructure freeGiftStructure;
    private MemberVerificationStructure memberVerificationStructure;
    private ReportAccessCodeStructure reportAccessCodeStructure;
    private ReportFreeGiftCodeStructure reportFreeGiftCodeStructure;
    private ReportSlotListStructure reportSlotListStructure;
    private EsunpayStructure esunpay;
    private MachineStructure machine;
    private DevSetStructure devSet;
    private GreenInvoiceStructure greenInvoice;
    private GreenpaySettingStructure greenpaySetting;
    private GreenpayMerchantStructure greenpayMerchant;
    private static DevXinYuanController devXinYuanController;
    public ReportFlowInfoStructure reportFlowInfoData;
    public PostInvoiceByGreenStructure postInvoiceByGreenData;
    public ReportInvoiceInfoStructure reportInvoiceInfoData;
    public InvoiceStructure invoiceData;
    public List<InvoiceItemStructure> invoiceItems;
    public ReportDispatchInfoStructure reportDispatchInfoData;
    public boolean isShowDialog;
    public boolean isDetectHost;
    public String suAccess;

    @Override
    public void onCreate() {
        super.onCreate();
        logs = new Logs(this.getClass());

        UsbDev.setUsbManager(getApplicationContext());
        Rs232Dev.setSuPath(getApplicationContext());
        Tools.setExternalFilesDir(getApplicationContext());

        instance = this;
        isShowDialog = false;
        suAccess = "";



        logs.info("============================ start ============================");

        try {
            UsbDev.getDeviceInfo(getApplicationContext());
        } catch (LogsUnsupportedOperationException e) {
            logs.warning(e);
        }

        this.comPort1ByXinYuan = ComPort.COM_PORT_1;
        this.comPort2ByNFCPay = ComPort.COM_PORT_2;
        this.comPort3ByFlower = ComPort.COM_PORT_3_FLOWER;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            this.comPort1ByXinYuan = ComPort.COM_PORT_S1;
            this.comPort2ByNFCPay = ComPort.COM_PORT_S2;
            this.comPort3ByFlower = ComPort.COM_PORT_S3_FLOWER;
        }

        this.devSet = new DevSetStructure(true,   false, false, true, true, true, false, false, false);
        this.machine = new MachineStructure("");
        this.esunpay = new EsunpayStructure("", "", "");
        this.greenInvoice = new GreenInvoiceStructure("", "", "", "");
        this.greenpaySetting = new GreenpaySettingStructure(
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "");
        this.greenpayMerchant = new GreenpayMerchantStructure(
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "",
                "");
        this.cashSetStructure = new CashSetStructure(true, true, true, true, true, true, true);
        this.accessCodeStructure = new AccessCodeStructure("");
        this.freeGiftStructure = new FreeGiftStructure("");

        this.memberVerificationStructure = new MemberVerificationStructure("", 0, "", 0);
        this.reportAccessCodeStructure = new ReportAccessCodeStructure("", 0, 0, "", "");
        this.reportFreeGiftCodeStructure = new ReportFreeGiftCodeStructure("", 0, "", 0, 0, "");
        this.reportSlotListStructure = new ReportSlotListStructure("","","","");
        this.fontendAdUrlString = new ArrayList<>();

        ToastHandlerMain toastHandlerMain = new ToastHandlerMain(getApplicationContext(), logs);

        if (this.devXinYuanController != null) {
            this.devXinYuanController.shutdown();
        }

        this.devXinYuanController = new DevXinYuanController(toastHandlerMain);
        devXinYuanController.start();

        devXinYuanController.addSendBuffer(devXinYuanController.getDevXinYuan().syncPackNo((byte)0x01));

        devXinYuanController.getReadBufferByNow(new DevController.ReadBufferOnScheduler(toastHandlerMain) {
            @Override
            protected HandlerMain setHandlerMain() {
                return getSrcHandlerMain();
            }

            @Override
            protected Class<?> setCls() {
                return getClass();
            }

            @Override
            public void readBufferOnScheduler(DevController devController, HandlerMain handlerMain) {
                int moneySwitchOkCount = 0;
                for(byte[] buffer: devController.getReadBufferByMax()) {
                    DevXinYuan.VMC vmc = DevXinYuanController.vmcMap.get(buffer[0]);
                    switch (vmc) {
                        case VMC_29_MONEY_SWITCH:
                            if (buffer[1] == 0x00) {
                                moneySwitchOkCount++;
                            }
                            break;
                    }
                }
            }
        });
        devXinYuanController.addSendBuffer(devXinYuanController.getDevXinYuan().inComeByIPC((byte) 0x08, 9999));
        devXinYuanController.addSendBuffer(devXinYuanController.getDevXinYuan().setMoneyType((byte) 0x01, (byte) 0x00, (byte) 0x00));
        devXinYuanController.addSendBuffer(devXinYuanController.getDevXinYuan().setMoneyType((byte) 0x02, (byte) 0x00, (byte) 0x00));

        initialSettingData();
        initialSystemSet(getApplicationContext());
        initialReportData();
        calculateScreenSize();

        this.uploadProductList = new ArrayList<>();
        this.productList = new ArrayList<>();
        initialProductData();
        this.slotMap = new HashMap<>();
        initialSlotData();
        this.marketingPlanList = new ArrayList<>();
        this.buyList = new ArrayList<>();


    }

    public void initialReportData() {
        setReportFlowInfoData(new ReportFlowInfoStructure("",0, "", "", "", 0, "", "", 0, 0, 0, new JSONArray()));
        setPostInvoiceByGreenData(new PostInvoiceByGreenStructure("","", 0, new InvoiceStructure("", "", "", ""), new ArrayList<>()));
        setReportInvoiceInfoData(new ReportInvoiceInfoStructure("", "", "", "", "", "", ""));
        setInvoiceData(new InvoiceStructure("", "", "", ""));
        setInvoiceItems(new ArrayList<>());
        setReportDispatchInfoData(new ReportDispatchInfoStructure("", 0, "", 0, 0, "", 0, "", "", 0, 0, 0));
        setReportAccessCodeStructure(new ReportAccessCodeStructure("", 0, 0, "", ""));
        setAccessCodeStructure(new AccessCodeStructure(""));
        setFreeGiftStructure(new FreeGiftStructure(""));
//        setReportFreeGiftCodeStructure(new ReportFreeGiftCodeStructure("", 0, "", 0, 0, ""));
        setMemberVerificationStructure(new MemberVerificationStructure("", 0, "", 0));
        //addReportDispatchInfoData(new ReportDispatchInfoStructure("", 0, "", 0, 0, "", 0, "", "", 0, 0, 0));
    }

    private void initialSystemSet(Context context) {
        MemoDao memoDao = new MemoDao(context);

        if (memoDao.existOnlyOne(MyApp.getInstance().getDevSet().getClass().getSimpleName())) {
            JSONObject jsonObject = memoDao.getOnlyOne(MyApp.getInstance().getDevSet().getClass().getSimpleName()).getData();
            logs.debug("initialSystemSet:" + jsonObject.toString());
            try {
                MyApp.getInstance().getDevSet().setVMC(jsonObject.getBoolean("VMC"));
                MyApp.getInstance().getDevSet().setElectic(jsonObject.getBoolean("Electic"));
                MyApp.getInstance().getDevSet().setShoppingCar(jsonObject.getBoolean("ShoppingCar"));
                MyApp.getInstance().getDevSet().setInvoice(jsonObject.getBoolean("Invoice"));
                MyApp.getInstance().getDevSet().setDevNFCPay(jsonObject.getBoolean("DevNFCPay"));
                MyApp.getInstance().getDevSet().setDevEsunPay(jsonObject.getBoolean("DevEsunPay"));
                MyApp.getInstance().getDevSet().setDevTapPay(jsonObject.getBoolean("DevTapPay"));
                MyApp.getInstance().getDevSet().setDevCash(jsonObject.getBoolean("DevCash"));
                MyApp.getInstance().getDevSet().setDevLinePay(jsonObject.getBoolean("DevLinePay"));
            } catch (JSONException e) {
                new Logs(MyApp.class).warning(e);
            }
        }

        if (memoDao.existOnlyOne(MyApp.getInstance().getCashSetStructure().getClass().getSimpleName())) {
            JSONObject jsonObject = memoDao.getOnlyOne(MyApp.getInstance().getCashSetStructure().getClass().getSimpleName()).getData();
            logs.debug("initialSystemSet:" + jsonObject.toString());
            try {
                MyApp.getInstance().getCashSetStructure().setBillF1000(jsonObject.getBoolean("BillF1000"));
                MyApp.getInstance().getCashSetStructure().setBillE500(jsonObject.getBoolean("BillE500"));
                MyApp.getInstance().getCashSetStructure().setBillD100(jsonObject.getBoolean("BillD100"));
                MyApp.getInstance().getCashSetStructure().setCoinF50(jsonObject.getBoolean("CoinF50"));
                MyApp.getInstance().getCashSetStructure().setCoinE10(jsonObject.getBoolean("CoinE10"));
                MyApp.getInstance().getCashSetStructure().setCoinD5(jsonObject.getBoolean("CoinD5"));
                MyApp.getInstance().getCashSetStructure().setCoinC1(jsonObject.getBoolean("CoinC1"));
            } catch (JSONException e) {
                new Logs(MyApp.class).warning(e);
            }
        }
    }
    public static void saveSystemSet(Context context) {
        MemoDao memoDao = new MemoDao(context);

        try {
            JSONObject systemSetByJsonObject = new JSONObject();
            systemSetByJsonObject.put("VMC", MyApp.getInstance().getDevSet().isVMC());
            systemSetByJsonObject.put("Electic", MyApp.getInstance().getDevSet().isElectic());
            systemSetByJsonObject.put("ShoppingCar", MyApp.getInstance().getDevSet().isShoppingCar());
            systemSetByJsonObject.put("Invoice", MyApp.getInstance().getDevSet().isInvoice());
            systemSetByJsonObject.put("DevNFCPay", MyApp.getInstance().getDevSet().isDevNFCPay());
            systemSetByJsonObject.put("DevEsunPay", MyApp.getInstance().getDevSet().isDevEsunPay());
            systemSetByJsonObject.put("DevTapPay", MyApp.getInstance().getDevSet().isDevTapPay());
            systemSetByJsonObject.put("DevCash", MyApp.getInstance().getDevSet().isDevCash());
            systemSetByJsonObject.put("DevLinePay", MyApp.getInstance().getDevSet().isDevLinePay());

            JSONObject cashSetByJsonObject = new JSONObject();
            cashSetByJsonObject.put("BillF1000", MyApp.getInstance().getCashSetStructure().isBillF1000());
            cashSetByJsonObject.put("BillE500", MyApp.getInstance().getCashSetStructure().isBillE500());
            cashSetByJsonObject.put("BillD100", MyApp.getInstance().getCashSetStructure().isBillD100());
            cashSetByJsonObject.put("CoinF50", MyApp.getInstance().getCashSetStructure().isCoinF50());
            cashSetByJsonObject.put("CoinE10", MyApp.getInstance().getCashSetStructure().isCoinE10());
            cashSetByJsonObject.put("CoinD5", MyApp.getInstance().getCashSetStructure().isCoinD5());
            cashSetByJsonObject.put("CoinC1", MyApp.getInstance().getCashSetStructure().isCoinC1());

            memoDao.insertOnlyOne(new MemoStructure(
                    MyApp.getInstance().getDevSet().getClass().getSimpleName(),
                    systemSetByJsonObject
                    , new JSONObject()));

            memoDao.mapUpdate();

            new Logs(MyApp.class).info("saveSystemSet count:" + memoDao.getCount(MyApp.getInstance().getDevSet().getClass().getSimpleName()));

            memoDao.insertOnlyOne(new MemoStructure(
                    MyApp.getInstance().getCashSetStructure().getClass().getSimpleName(),
                    cashSetByJsonObject
                    , new JSONObject()));

            memoDao.mapUpdate();

            new Logs(MyApp.class).info("saveSystemSet count:" + memoDao.getCount(MyApp.getInstance().getCashSetStructure().getClass().getSimpleName()));
        } catch (JSONException e) {
            new Logs(MyApp.class).warning(e);
        }
    }

    public static void updateLog(Context context) {

    }

    public void initialSettingData() {
        SettingsDao settingsDao = new SettingsDao(getApplicationContext());

        if (MyApp.getInstance().getMachine().getMachineID().isEmpty()) {
            SettingStructure setting = settingsDao.getOne(MyApp.getInstance().getMachine().getClass().getSimpleName());
            logs.info("initialSettingData:" + setting.toString());
            MyApp.getInstance().getMachine().setMachineID(setting.getData(1));
        }

        if (MyApp.getInstance().getGreenInvoice().getGreenMerchantID().isEmpty()) {
            SettingStructure setting = settingsDao.getOne(MyApp.getInstance().getGreenInvoice().getClass().getSimpleName());
            MyApp.getInstance().getGreenInvoice().setGreenMerchantID(setting.getData(0));
            MyApp.getInstance().getGreenInvoice().setGreenHashKey(setting.getData(1));
            MyApp.getInstance().getGreenInvoice().setGreenHashIV(setting.getData(2));
            MyApp.getInstance().getGreenInvoice().setGreenEmail(setting.getData(3));
        }

        if (MyApp.getInstance().getEsunpay().getStoreID().isEmpty()) {
            SettingStructure setting = settingsDao.getOne(MyApp.getInstance().getEsunpay().getClass().getSimpleName());
            MyApp.getInstance().getEsunpay().setStoreID(setting.getData(0));
            MyApp.getInstance().getEsunpay().setTermID(setting.getData(1));
            MyApp.getInstance().getEsunpay().setHash(setting.getData(2));
        }

        if (!MyApp.getInstance().getGreenpaySetting().getAppId().isEmpty()) {
            SettingStructure setting = settingsDao.getOne(MyApp.getInstance().getGreenpaySetting().getClass().getSimpleName());
            MyApp.getInstance().getGreenpaySetting().setAppId(setting.getData(0));
            MyApp.getInstance().getGreenpaySetting().setAppKey(setting.getData(1));
            MyApp.getInstance().getGreenpaySetting().setPartnerKey(setting.getData(2));
            MyApp.getInstance().getGreenpaySetting().setCtbcMerchantId(setting.getData(3));
            MyApp.getInstance().getGreenpaySetting().setNcccMerchantId(setting.getData(4));
            MyApp.getInstance().getGreenpaySetting().setTaishinMerchantId(setting.getData(5));
            MyApp.getInstance().getGreenpaySetting().setEsunMerchantId(setting.getData(6));
            MyApp.getInstance().getGreenpaySetting().setGpuseMerchantId(setting.getData(7));

            SettingStructure setting2 = settingsDao.getOne(MyApp.getInstance().getGreenpayMerchant().getClass().getSimpleName());
            MyApp.getInstance().getGreenpayMerchant().setLineMerchantId(setting2.getData(0));
            MyApp.getInstance().getGreenpayMerchant().setPsMerchantId(setting2.getData(1));
            MyApp.getInstance().getGreenpayMerchant().setEasyMerchantId(setting2.getData(2));
            MyApp.getInstance().getGreenpayMerchant().setPiMerchantId(setting2.getData(3));
            MyApp.getInstance().getGreenpayMerchant().setJkoMerchantId(setting2.getData(4));
            MyApp.getInstance().getGreenpayMerchant().setDirectMerchantId(setting2.getData(5));
            MyApp.getInstance().getGreenpayMerchant().setAppleMerchantId(setting2.getData(6));
            MyApp.getInstance().getGreenpayMerchant().setGoogleMerchantId(setting2.getData(7));
            MyApp.getInstance().getGreenpayMerchant().setSamsungMerchantId(setting2.getData(8));
            MyApp.getInstance().getGreenpayMerchant().setAtomeMerchantId(setting2.getData(9));
        }

        if (MyApp.getInstance().getFontendAdUrlString().isEmpty()) {
            List<SettingStructure> settingList = settingsDao.getWhere(VideoEoxPlayer.class.getSimpleName());
            for (SettingStructure setting: settingList) {
                MyApp.getInstance().getFontendAdUrlString().add(setting.getData(0));
            }
        }

        settingsDao.close();
    }
    private void initialProductData() {
        if (MyApp.getInstance().getProductList().isEmpty()) {
            ProductsDao productsDao = new ProductsDao(this);
            for (ProductStructure product: productsDao.getAll()) {
                MyApp.getInstance().getProductList().add(product);
            }
            productsDao.close();
            logs.info("product count:"+ MyApp.getInstance().getProductList().size());
        }
    }

    public void initialSlotData() {
        logs.debug("initialSlotData");

        //開架構
        for (SlotField slotField: SlotField.values()) {
            if (!getInstance().getSlotMap().containsKey(slotField.getField())) {
                getInstance().getSlotMap().put(slotField.getField(), new ArrayList<>());
                logs.info(slotField.getField()+" slot db open");
            }
        }

        //查詢資料庫
        SlotsDao slotsDao = new SlotsDao(this);
        Map<Integer, List<SlotStructure>> slotMapNew = slotsDao.getAll();
        for (SlotField slotField: SlotField.values()) {
            if (getInstance().getSlotList(slotField.getField()).isEmpty() && slotMapNew.get(slotField.getField()) != null && !slotMapNew.get(slotField.getField()).isEmpty()) {
                List<SlotStructure> slotList = slotMapNew.get(slotField.getField());
                for (SlotStructure slot : slotList) {
                    getInstance().getSlotList(slotField.getField()).add(slot);
                }
                logs.info(slotField.getField()+" slot db count:"+getInstance().getSlotList(slotField.getField()).size());
            }
        }
        slotsDao.close();

        //無資料就初始化
        if (getInstance().getSlotList(SlotField.VMC.getField()).isEmpty()) {
            for (int i = 1; i <= 60; i++) {
                getInstance().getSlotList(SlotField.VMC.getField()).add(new SlotStructure(SlotField.VMC.getField(), i,
                        new ProductStructure("?", "", "", 0, 0, 0, 0, "", "","",""),
                        0));
            }
            logs.info(SlotField.VMC.getField()+" slot init count:" + getInstance().getSlotList(SlotField.VMC.getField()).size());
        }

        if (getInstance().getSlotList(SlotField.ELECTRIC.getField()).isEmpty()) {
            for (int i = 1; i <= 10; i++) {
                getInstance().getSlotList(SlotField.ELECTRIC.getField()).add(new SlotStructure(SlotField.ELECTRIC.getField(), i,
                        new ProductStructure("?", "", "", 0, 0, 0, 0, "", "","",""),
                        0));
            }
            logs.info(SlotField.ELECTRIC.getField()+" slot init count:" + getInstance().getSlotList(SlotField.ELECTRIC.getField()).size());
        }

        if (getInstance().getSlotList(SlotField.FLOWER.getField()).isEmpty()) {
            for (int i = 1; i <= 10; i++) {
                getInstance().getSlotList(SlotField.FLOWER.getField()).add(new SlotStructure(SlotField.FLOWER.getField(), i,
                        new ProductStructure("?", "", "", 0, 0, 0, 0, "", "","",""),
                        0));
            }
            logs.info(SlotField.FLOWER.getField()+" slot init count:" + getInstance().getSlotList(SlotField.FLOWER.getField()).size());
        }
    }

    private void calculateScreenSize() {
        // 取得 WindowManager
        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();

        // 取得螢幕尺寸
        if (wm != null) {
            wm.getDefaultDisplay().getMetrics(metrics);
            this.screenWidthPx = metrics.widthPixels;
            this.screenHeightPx = metrics.heightPixels;
            density = metrics.density;  // 保存密度值
        }
    }

    // 新增 px 轉 dp 的函數
    public int pxToDp(int px) {
        return Math.round(px / density);
    }

    // 新增 dp 轉 px 的函數（可選）
    public int dpToPx(int dp) {
        return Math.round(dp * density);
    }

    public int getScreenWidthPx() {
        return screenWidthPx;
    }

    public int getScreenHeightPx() {
        return screenHeightPx;
    }

    public ComPort getComPort1ByXinYuan() {
        return comPort1ByXinYuan;
    }

    public ComPort getComPort2ByNFCPay() {
        return comPort2ByNFCPay;
    }

    public List<ProductStructure> getUploadProductList() {
        return uploadProductList;
    }
    public List<DeliveryStructure> getUploadDeliveryList() {
        return uploadDeliveryList;
    }

    public List<ProductStructure> getProductList() {
        return productList;
    }

    public List<DeliveryStructure> getDeliveryList() {
        return deliveryList;
    }

    public List<String> getFontendAdUrlString() {
        return fontendAdUrlString;
    }

    public ProductStructure getProduct(String productId) throws LogsNoSuchElementException {
        for (ProductStructure product: getProductList()) {
            if (product.getProductID().equals(productId)) {
                return product;
            }
        }

        throw new LogsNoSuchElementException(logs, "get product "+productId+" not found");
    }

    public Map<Integer, List<SlotStructure>> getSlotMap() {
        return slotMap;
    }

    public List<SlotStructure> getSlotList(int field) {
        return getSlotMap().get(field);
    }

    public SlotStructure getSlotData(int field, int slot) throws LogsEmptyException {
        for (SlotStructure slotData: getSlotList(field)) {
            if (slotData.getSlot() == slot) {
                return slotData;
            }
        }

        throw new LogsEmptyException(logs, "Slot data not found");
    }

    public SlotStructure getSlotDataByPid(int field, String pid) throws LogsEmptyException {
        for (SlotStructure slotData: getSlotList(field)) {
            if (slotData.getProduct().getProductID().equals(String.valueOf(pid))) {
                return slotData;
            }
        }

        throw new LogsEmptyException(logs, "Slot data not found");
    }

    public SlotStructure getSlotDataByPid(String pid) throws LogsEmptyException {
        for (SlotField slotField: SlotField.values()) {
            try {
                return getSlotDataByPid(slotField.getField(), pid);
            } catch (LogsEmptyException e) {

            }
        }

        throw new LogsEmptyException(logs, "Slot data not found");
    }

    public List<MarketingPlanStructure> getMarketingPlanList() {
        return marketingPlanList;
    }

    public List<BuyStructure> getBuyList() {
        return buyList;
    }

    public EsunpayStructure getEsunpay() {
        return esunpay;
    }

    public MachineStructure getMachine() {
        return machine;
    }

    public GreenInvoiceStructure getGreenInvoice() {
        return greenInvoice;
    }

    public GreenpaySettingStructure getGreenpaySetting() {
        return greenpaySetting;
    }

    public GreenpayMerchantStructure getGreenpayMerchant() {
        return greenpayMerchant;
    }

    public DevXinYuanController getDevXinYuanController() {
        return devXinYuanController;
    }

    public void setReportFlowInfoData(ReportFlowInfoStructure reportFlowInfoData) {
        this.reportFlowInfoData = reportFlowInfoData;
    }

    public ReportFlowInfoStructure getReportFlowInfoData() {
        return reportFlowInfoData;
    }

    public void setPostInvoiceByGreenData(PostInvoiceByGreenStructure postInvoiceByGreenData) {
        this.postInvoiceByGreenData = postInvoiceByGreenData;
    }

    public PostInvoiceByGreenStructure getPostInvoiceByGreenData() {
        return postInvoiceByGreenData;
    }

    public void setReportInvoiceInfoData(ReportInvoiceInfoStructure reportInvoiceInfoData) {
        this.reportInvoiceInfoData = reportInvoiceInfoData;
    }

    public void setReportAccessCodeStructure(ReportAccessCodeStructure reportAccessCodeStructure) {
        this.reportAccessCodeStructure = reportAccessCodeStructure;
    }

    public void setReportFreeGiftCodeStructure(ReportFreeGiftCodeStructure reportFreeGiftCodeStructure) {
        this.reportFreeGiftCodeStructure = reportFreeGiftCodeStructure;
    }

    public ReportFreeGiftCodeStructure getReportFreeGiftCodeStructure() {
        return reportFreeGiftCodeStructure;
    }

    public ReportInvoiceInfoStructure getReportInvoiceInfoData() {
        return reportInvoiceInfoData;
    }

    public void setInvoiceData(InvoiceStructure invoiceData) {
        this.invoiceData = invoiceData;
    }

    public InvoiceStructure getInvoiceData() {
        return invoiceData;
    }

    public List<InvoiceItemStructure> getInvoiceItems() {
        return invoiceItems;
    }

    public void setInvoiceItems(List<InvoiceItemStructure> invoiceItems) {
        this.invoiceItems = invoiceItems;
    }

    public void setReportDispatchInfoData(ReportDispatchInfoStructure reportDispatchInfoData) {
        this.reportDispatchInfoData = reportDispatchInfoData;
    }

    public ReportDispatchInfoStructure getReportDispatchInfoData() {
        return reportDispatchInfoData;
    }

    public DevSetStructure getDevSet() {
        return devSet;
    }


    public ReportAccessCodeStructure getReportAccessCodeStructure() {
        return reportAccessCodeStructure;
    }

    public ReportSlotListStructure getReportSlotListStructure(){
        return reportSlotListStructure;
    }

    public CashSetStructure getCashSetStructure() {
        return cashSetStructure;
    }

    public AccessCodeStructure getAccessCodeStructure() {
        return accessCodeStructure;
    }

    public void setAccessCodeStructure(AccessCodeStructure accessCodeStructure) {
        this.accessCodeStructure = accessCodeStructure;
    }

    public FreeGiftStructure getFreeGiftStructure() {
        return freeGiftStructure;
    }

    public void setFreeGiftStructure(FreeGiftStructure freeGiftStructure) {
        this.freeGiftStructure = freeGiftStructure;
    }

    public MemberVerificationStructure getMemberVerificationStructure() {
        return memberVerificationStructure;
    }

    public void setMemberVerificationStructure(MemberVerificationStructure memberVerificationStructure) {
        this.memberVerificationStructure = memberVerificationStructure;
    }

    public int getCloseSlot() {
        return closeSlot;
    }

    public void setCloseSlot(int closeSlot) {
        this.closeSlot = closeSlot;
    }

    public boolean isShowDialog() {
        return isShowDialog;
    }

    public void setShowDialog(boolean showDialog) {
        isShowDialog = showDialog;
    }

    public String getSuAccess() {
        return suAccess;
    }

    public void setSuAccess(String suAccess) {
        this.suAccess = suAccess;
    }

    public boolean isDetectHost() {
        return isDetectHost;
    }

    public void setDetectHost(boolean detectHost) {
        isDetectHost = detectHost;
    }
}
